package CalendarProgram;


/*Contents of CalendarProgran.class */

//Import packages
import javax.sql.rowset.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
import javax.swing.table.*;

import dataBaseWrapper.DataBaseConnection;

import java.awt.*;
import java.awt.event.*;
import java.sql.*;
import java.util.*;

/** Contains the main program and interface for the program. Sets up Swing, and processes user input.
 * 
 *
 */
public class CalendarProgram{
	static JLabel lblMonth, lblYear, lblWeek, lblSelectUser, lblSelectEvent, lblSelectLocation,
					lblWeatherIcon1, lblWeatherIcon2, lblWeatherIcon3, lblWeatherIcon4, lblWeatherIcon5, 
					lblWeatherIcon6, lblWeatherIcon7, lblTitelTemp, lblTemp1, lblTemp2, lblTemp3, lblTemp4, 
					lblTemp5, lblTemp6, lblTemp7, lblLoading;
	static JButton btnPrevMonth, btnNextMonth, btnPrevWeek, btnNextWeek, btnAddUser, btnAddEvent, btnGetForecast;
	static JTable tblCalendar;
	static JComboBox<Integer> cmbYear;
	static JComboBox<String> cmbUserSelect, cmbEventSelect;
	static JFrame frmMain;
	static Container pane;
	static DefaultTableModel mtblCalendar; //Table model
	static TableColumnModel columns = new DefaultTableColumnModel();
	static JScrollPane stblCalendar; //The scrollpane
	static JTabbedPane tabPane; //The tab pane
	static JPanel pnlCalendar, pnlSettings; //The 2 tabs
	static JSeparator separator1, separator2;
	static JTextField txtEnterNewUsername, txtEnterNewEventName, txtEnterLocation;
	static ImageIcon icon;
	static int realYear, realMonth, realWeek, realDay, currentYear, currentMonth, currentWeek;
	static String selectedLocation;
	static ArrayList<JLabel> temperatureLblList, iconLblList;
	static String selectedUser,selectedEvent;
	static Integer selectedUserID,selectedUserEvent;
	
	/** Sets up the Swing interface, and writes in the days, month, weeks and years.
	 * @param args Command-line parameters, are not used in this implementation.
	 */
	/**
	 * @param args
	 */
	public static void main (String args[])
	{
		//Set look and feel
		try {UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());}
		catch (ClassNotFoundException e) {}
		catch (InstantiationException e) {}
		catch (IllegalAccessException e) {}
		catch (UnsupportedLookAndFeelException e) {}
		
		DataBaseConnection.loadDriver(); //load drivers for database connection

		//Prepare frame
		frmMain = new JFrame ("SunTime"); //Create frame
		frmMain.setSize(334, 579); //Set size to 334x579 pixels
		pane = frmMain.getContentPane(); //Get content pane
		pane.setLayout(null); //Apply null layout
		frmMain.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //Close when X is clicked

		//Create controls
		lblMonth = new JLabel ("January");
		lblYear = new JLabel ("Change year:");
		lblWeek = new JLabel("Week 1");
		lblSelectUser = new JLabel("Select User:");
		lblSelectEvent = new JLabel("Select Event:");
		lblSelectLocation = new JLabel("Select Location:");
		lblLoading = new JLabel("Loading, please wait");
		lblWeatherIcon1 = new JLabel("icon1");
		lblWeatherIcon2 = new JLabel("icon2");
		lblWeatherIcon3 = new JLabel("icon3");
		lblWeatherIcon4 = new JLabel("icon4");
		lblWeatherIcon5 = new JLabel("icon5");
		lblWeatherIcon6 = new JLabel("icon6");
		lblWeatherIcon7 = new JLabel("icon7");
		lblTitelTemp = new JLabel("Temp:");
		lblTemp1 = new JLabel("Temp1");
		lblTemp2 = new JLabel("Temp2");
		lblTemp3 = new JLabel("Temp3");
		lblTemp4 = new JLabel("Temp4");
		lblTemp5 = new JLabel("Temp5");
		lblTemp6 = new JLabel("Temp6");
		lblTemp7 = new JLabel("Temp7");
		temperatureLblList = new ArrayList<JLabel>();
		iconLblList = new ArrayList<JLabel>();
		cmbYear = new JComboBox();
		cmbUserSelect = new JComboBox();
		cmbEventSelect = new JComboBox();
		btnPrevMonth = new JButton ("<<");
		btnNextMonth = new JButton (">>");
		btnPrevWeek = new JButton ("<<");
		btnNextWeek = new JButton (">>");
		btnAddUser  = new JButton("Add user");
		btnAddEvent  = new JButton("Add Event");
		btnGetForecast = new JButton("Get forecast");
		mtblCalendar = new DefaultTableModel(){public boolean isCellEditable(int rowIndex, int mColIndex){return false;}};
		tblCalendar = new JTable(mtblCalendar);
		stblCalendar = new JScrollPane(tblCalendar);
		tabPane = new JTabbedPane(JTabbedPane.TOP); //The tabs at the top
		pnlCalendar = new JPanel(null);
		pnlSettings = new JPanel(null);
		separator1 = new JSeparator();
		separator2 = new JSeparator();
		txtEnterNewUsername = new JTextField();
		txtEnterNewEventName = new JTextField();
		txtEnterLocation = new JTextField();
		icon = new ImageIcon("resources/test.gif");
		selectedUserID = 1;
		selectedUserEvent = 1;
		
		//Set text in textfields
		txtEnterNewUsername.setText("New username");		
		txtEnterNewEventName.setText("New event name");
		txtEnterLocation.setText("Enter city");

		//Set border
		tabPane.setBounds(0, 0, 328, 553);
		pnlCalendar.setBorder(BorderFactory.createTitledBorder("Calendar"));
		pnlSettings.setBorder(BorderFactory.createTitledBorder("Settings"));
		Color color = UIManager.getColor("Table.gridColor");
		MatteBorder border = new MatteBorder(1, 1, 0, 0, color);
		tblCalendar.setBorder(border);
		
		//Set Font
		lblTitelTemp.setFont(new Font("Dialog", Font.BOLD, 11));
		lblTemp1.setFont(new Font("Dialog", Font.PLAIN, 11));
		lblTemp2.setFont(new Font("Dialog", Font.PLAIN, 11));
		lblTemp3.setFont(new Font("Dialog", Font.PLAIN, 11));
		lblTemp4.setFont(new Font("Dialog", Font.PLAIN, 11));
		lblTemp5.setFont(new Font("Dialog", Font.PLAIN, 11));
		lblTemp6.setFont(new Font("Dialog", Font.PLAIN, 11));
		lblTemp7.setFont(new Font("Dialog", Font.PLAIN, 11));
		
		//Register action listeners
		btnPrevMonth.addActionListener(new btnPrevMonth_Action());
		btnNextMonth.addActionListener(new btnNextMonth_Action());
		btnPrevWeek.addActionListener(new btnPrevWeek_Action());
		btnNextWeek.addActionListener(new btnNextWeek_Action());
		btnAddUser.addActionListener(new btnAddUser_Action());
		btnAddEvent.addActionListener(new btnAddEvent_Action());
		btnGetForecast.addActionListener(new btnGetForecast_Action());
		cmbYear.addActionListener(new cmbYear_Action());
		cmbUserSelect.addActionListener(new cmbUserSelect_Action());
		cmbEventSelect.addActionListener(new cmbUserSelect_Action());
		//Action listener for clicking on the calendar
		tblCalendar.addMouseListener(new MouseAdapter() 
		{
			public void mouseClicked(MouseEvent arg0) 
			{
				int rowIndex = tblCalendar.getSelectedRow();
				int colIndex = tblCalendar.getSelectedColumn();
				try
				{
					
								int[] properties = {selectedUserID,selectedUserID,currentYear,currentMonth,currentWeek,rowIndex,colIndex};
								String[] propertiesString = new String[properties.length];
								for (int i = 0; i < properties.length; i++) 
								{
									propertiesString[i] = Integer.toString(properties[i]);
								}
								
								if(mtblCalendar.getValueAt(rowIndex, colIndex) != null)
								{
									DataBaseConnection.deleteEvent(propertiesString);
								}
								else
								{
									DataBaseConnection.insertData(propertiesString,"SunTime_EventDays");
								}
				}
				catch (SQLException e)
				{
					e.printStackTrace();
				}
				finally
				{
					refreshCalendar(currentMonth,currentYear,currentWeek);
				}
			
			}
		});

		//Add everything to pane
		pane.add(tabPane);
		tabPane.addTab("Calendar", null, pnlCalendar, null);
		tabPane.addTab("Settings", null, pnlSettings, null);
		pnlCalendar.add(lblWeek);
		pnlCalendar.add(lblMonth);
		pnlCalendar.add(lblYear);
		pnlSettings.add(lblSelectUser);
		pnlSettings.add(lblSelectEvent);
		pnlSettings.add(lblSelectLocation);
		pnlCalendar.add(lblLoading);
		pnlCalendar.add(lblWeatherIcon1);
		pnlCalendar.add(lblWeatherIcon2);
		pnlCalendar.add(lblWeatherIcon3);
		pnlCalendar.add(lblWeatherIcon4);
		pnlCalendar.add(lblWeatherIcon5);
		pnlCalendar.add(lblWeatherIcon6);
		pnlCalendar.add(lblWeatherIcon7);
		pnlCalendar.add(lblTitelTemp);
		pnlCalendar.add(lblTemp1);
		pnlCalendar.add(lblTemp2);
		pnlCalendar.add(lblTemp3);
		pnlCalendar.add(lblTemp4);
		pnlCalendar.add(lblTemp5);
		pnlCalendar.add(lblTemp6);
		pnlCalendar.add(lblTemp7);
		pnlCalendar.add(cmbYear);
		pnlSettings.add(cmbUserSelect);
		pnlSettings.add(cmbEventSelect);
		pnlCalendar.add(btnPrevMonth);
		pnlCalendar.add(btnNextMonth);
		pnlCalendar.add(btnPrevWeek);
		pnlCalendar.add(btnNextWeek);
		pnlSettings.add(btnAddUser);
		pnlSettings.add(btnAddEvent);
		pnlCalendar.add(btnGetForecast);
		pnlCalendar.add(stblCalendar);
		pnlSettings.add(txtEnterNewUsername);
		pnlSettings.add(txtEnterNewEventName);
		pnlSettings.add(txtEnterLocation);
		pnlSettings.add(separator1);
		pnlSettings.add(separator2);

		//Add temperature labels and icon labels to their respective arrays
		temperatureLblList.add(lblTemp1);
		temperatureLblList.add(lblTemp2);
		temperatureLblList.add(lblTemp3);
		temperatureLblList.add(lblTemp4);
		temperatureLblList.add(lblTemp5);
		temperatureLblList.add(lblTemp6);
		temperatureLblList.add(lblTemp7);
		
		iconLblList.add(lblWeatherIcon1);
		iconLblList.add(lblWeatherIcon2);
		iconLblList.add(lblWeatherIcon3);
		iconLblList.add(lblWeatherIcon4);
		iconLblList.add(lblWeatherIcon5);
		iconLblList.add(lblWeatherIcon6);
		iconLblList.add(lblWeatherIcon7);
		
		//Set bounds
		pnlCalendar.setBounds(0, 0, 318, 531);
		lblWeek.setBounds(160-lblWeek.getPreferredSize().width/2, 75, 100, 25);	//varies the size according to text length
		lblMonth.setBounds(160-lblMonth.getPreferredSize().width/2, 25, 100, 25);
		lblYear.setBounds(10, 446, 80, 20);
		lblSelectUser.setBounds(10, 22, 88, 16);
		lblSelectEvent.setBounds(10, 97, 88, 16);
		lblSelectLocation.setBounds(10, 175, 114, 16);
		lblLoading.setBounds(10, 497, 142, 16);
		lblWeatherIcon1.setBounds(47, 118, 37, 38);
		lblWeatherIcon2.setBounds(82, 118, 37, 38);
		lblWeatherIcon3.setBounds(117, 118, 37, 38);
		lblWeatherIcon4.setBounds(152, 118, 37, 38);
		lblWeatherIcon5.setBounds(187, 118, 37, 38);
		lblWeatherIcon6.setBounds(222, 118, 37, 38);
		lblWeatherIcon7.setBounds(257, 118, 37, 38);
		lblTitelTemp.setBounds(10, 167, 37, 16);
		lblTemp1.setBounds(47, 167, 37, 16);
		lblTemp2.setBounds(82, 167, 37, 16);
		lblTemp3.setBounds(117, 167, 37, 16);
		lblTemp4.setBounds(152, 168, 37, 16);
		lblTemp5.setBounds(187, 168, 37, 16);
		lblTemp6.setBounds(222, 168, 37, 16);
		lblTemp7.setBounds(257, 167, 37, 16);
		cmbYear.setBounds(222, 446, 80, 20);
		cmbUserSelect.setBounds(131, 18, 76, 25);
		cmbEventSelect.setBounds(131, 93, 76, 25);
		btnPrevMonth.setBounds(10, 25, 50, 25);
		btnNextMonth.setBounds(260, 25, 50, 25);
		btnPrevWeek.setBounds(10, 75, 50, 25);
		btnNextWeek.setBounds(260, 75, 50, 25);
		btnAddUser.setBounds(131, 47, 98, 26);
		btnAddEvent.setBounds(131, 122, 98, 26);
		btnGetForecast.setBounds(187, 492, 124, 26);
		stblCalendar.setBounds(10, 184, 300, 250);
		separator1.setBounds(20, 85, 274, 3);
		separator2.setBounds(10, 160, 274, 3);
		txtEnterNewUsername.setBounds(10, 50, 114, 20);
		txtEnterNewUsername.setColumns(10);
		txtEnterNewEventName.setBounds(10, 125, 114, 20);
		txtEnterNewEventName.setColumns(10);
		txtEnterLocation.setBounds(131, 173, 114, 20);
		txtEnterLocation.setColumns(10);
				
		//Make frame visible
		frmMain.setResizable(false);
		frmMain.setVisible(true);
		
		//Get real month/year
		GregorianCalendar cal = new GregorianCalendar(); //Create calendar
		cal.setMinimalDaysInFirstWeek(1); //Choose to acknowledge a week as the first week even if it isn't a full 7 day week
		realDay = cal.get(GregorianCalendar.DAY_OF_MONTH); //Get day
		realWeek = cal.get(GregorianCalendar.WEEK_OF_MONTH); //Get week of the month
		realMonth = cal.get(GregorianCalendar.MONTH); //Get month
		realYear = cal.get(GregorianCalendar.YEAR); //Get year
		currentMonth = realMonth; //Match month, year and week
		currentYear = realYear;
		currentWeek = realWeek-1; // using week_of_month means week 1 == 1; while we started counting from 0
		
		//Add headers
		//Columns
		String[] headers = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"}; //All headers
		for (int i=0; i<7; i++)
		{
			mtblCalendar.addColumn(headers[i]);
		}
		//Rows
		String[] hours = {"Day","9:00","10:00","11:00","12:00","13:00","14:00","15:00","16:00","17:00","18:00","19:00","20:00","21:00","22:00","23:00"};
		JList hourHeader = new JList(hours);
		hourHeader.setFixedCellHeight(38);
		hourHeader.setBorder(border);
		stblCalendar.setRowHeaderView(hourHeader);
		tblCalendar.getParent().setBackground(tblCalendar.getBackground()); //Set background
		
		//No resize/reorder
		tblCalendar.getTableHeader().setResizingAllowed(false);
		tblCalendar.getTableHeader().setReorderingAllowed(false);

		//Single cell selection
		tblCalendar.setColumnSelectionAllowed(true);
		tblCalendar.setRowSelectionAllowed(true);
		tblCalendar.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

		//Set row/column count
		tblCalendar.setRowHeight(38);
		mtblCalendar.setColumnCount(7);
		mtblCalendar.setRowCount(16);

		//Populate year combo box
		for (int i=realYear-100; i<=realYear+100; i++)
		{
			cmbYear.addItem(i);
		}
		cmbYear.setSelectedItem(2014);
		//Refresh calendar
		refreshCalendar (realMonth, realYear, realWeek); //Refresh calendar
		
	}
	
	/** Refreshes the calendar, switching days in the header, loading events and users and applying renderers.
	 * The three parameters are used to determine the dates of the current week.
	 * @param month 
	 * @param year
	 * @param week
	 */
	public static void refreshCalendar(int month, int year, int week)
	{
		//Variables
		String[] months =  {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
		String[] weeks =  {"Week 1", "Week 2", "Week 3", "Week 4", "Week 5", "Week 6", "week 7"};
		int nod, som, now; //Number Of Days, Start Of Month, Number Of Weeks (in a month)
		
		//Get first day of month and number of days
		GregorianCalendar cal = new GregorianCalendar(year, month, 1);
		cal.setMinimalDaysInFirstWeek(1);
		nod = cal.getActualMaximum(GregorianCalendar.DAY_OF_MONTH);
		som = cal.get(GregorianCalendar.DAY_OF_WEEK)-1; // substract to match with the correct day see "draw calendar week by week"
		if(som == 0)  // in the normal calendar api sunday is day "1", so minus 1 it's day "0" which should be day "7"
		{
			som =7;
		}
		now = cal.getActualMaximum(GregorianCalendar.WEEK_OF_MONTH)-1; // substract one because the string[] weeks starts from 0, while week_of_month starts from 1
		
		//Allow/disallow buttons
		btnPrevMonth.setEnabled(true);
		btnNextMonth.setEnabled(true);
		btnPrevWeek.setEnabled(true);
		btnNextWeek.setEnabled(true);
		if (month == 0 && year <= realYear-10){btnPrevMonth.setEnabled(false);} //Too early
		if (month == 11 && year >= realYear+100){btnNextMonth.setEnabled(false);} //Too late
		if (week == 0 && month == 0 && year <= realYear-10){btnPrevWeek.setEnabled(false);} //Too early
		if (week == now && month == 11 && year >= realYear+100){btnNextWeek.setEnabled(false);} //Too late
		lblMonth.setText(months[month]); //Refresh the month label (at the top)
		lblMonth.setBounds(160-lblMonth.getPreferredSize().width/2, 25, 180, 25); //Re-align label with calendar
		lblWeek.setText(weeks[week]); //Refresh the week label (at the top)
		lblWeek.setBounds(160-lblWeek.getPreferredSize().width/2, 75, 180, 25); //Re-align label with calendar		
		cmbYear.setSelectedItem(String.valueOf(year)); //Select the correct year in the combo box
		
		//Clear table
		for (int i=0; i<16; i++)
		{
			for (int j=0; j<7; j++)
			{
				mtblCalendar.setValueAt(null, i, j);
			}
		}
		
		//Draw calendar week by week
		if(currentWeek == 0) //Draw the first week
		{
			for (int i=1; i<=(8-som); i++)
			{
				int row = 0;
				int column  =  ((i+som-2)%7);
				if(column == -1)
				{
					column = 6;
				}
				mtblCalendar.setValueAt(i, row, column);
			}
		}
		else //all other weeks
		{
			for (int i=(currentWeek*7)+2-som; i<=(currentWeek*7)+8-som; i++)
			{
				if(i <=nod)
				{
					int row = 0;
					int column = ((i+som-2)%7);
					if(column == -1)
					{
						column = 6;
					}
					mtblCalendar.setValueAt(i, row, column);
				}
			}
		}
		
		//Apply renderers
		tblCalendar.setDefaultRenderer(tblCalendar.getColumnClass(0), new tblCalendarRenderer());
		
		//Remove loading indicator
		lblLoading.setText("Ready!");
		
		//Load users and events from database
		try
		{
			Object currentUser = cmbUserSelect.getSelectedItem();
			Object currentEvent = cmbEventSelect.getSelectedItem();
			cmbUserSelect.removeAllItems();
			cmbEventSelect.removeAllItems();
			CachedRowSet users = DataBaseConnection.getUsers();
			CachedRowSet events = DataBaseConnection.getEvents();
			while(users.next())
			{
				cmbUserSelect.addItem(users.getString(2));
			}
			while(events.next())
			{
				cmbEventSelect.addItem(events.getString(2));
			}
				cmbUserSelect.setSelectedItem(currentUser);
				cmbEventSelect.setSelectedItem(currentEvent);
		}
		catch (SQLException e)
		{
			e.printStackTrace();
		}	
				
		//Load events and populate table.
		try
		{
			CachedRowSet eventDays = DataBaseConnection.getEventData();
			while(eventDays.next())
			{
				//Iterate through events, and find events that apply to the current week.
				if(eventDays.getInt("Year") == currentYear && eventDays.getInt("Month") == currentMonth && eventDays.getInt("Week") == currentWeek)
				{
					mtblCalendar.setValueAt(99, eventDays.getInt("Row"), eventDays.getInt("ColumnPos"));
				}
			}
		}
		catch (SQLException e)
		{
			e.printStackTrace();
		}
	}
	
	/** Performs the weather forecast, calling the Forecast and Geocode classes and displaying the weather and temperature on the labels and icons.
	 * 
	 */
	public static void doForecast()
	{
		
		String dayString = "";
		String monthString = "";
		int day;
		int month;
		for(int column =0;column<7;column++)
		{
			lblLoading.setText("Loading...");
			Object calenderValue = mtblCalendar.getValueAt(0, column);
			if(calenderValue != null)
			{
				day = Integer.parseInt(calenderValue.toString());
				if(day<10)
				{
					dayString = ("0"+day);
				}
				else
				{
					dayString = "" + day;
				}
				month = (realMonth+1);
				if(month<10)
				{
					monthString = ("0"+month);
				}
				else
				{
					monthString = "" + month;
				}
				//get forecast for current location
				//time format = [YYYY]-[MM]-[DD]T[HH]:[MM]:[SS] e.g. 2013-05-06T12:00:00-0400
				String time = realYear+"-"+ monthString +"-"+dayString+"T"+"19:00:00-0400";
				//address format = "address,city,state,zipcode" e.g. "1Diestsestraat,Leuven,3000"
				//String address = Number+Street+City+Postcode;
				String address = txtEnterLocation.getText();
				Forecast f = new Forecast(time,address);
				
				//Display the acquired information
				double temperature = f.getTemperatureMax();
				temperatureLblList.get(column).setText(String.valueOf(temperature));
				iconLblList.get(column).setIcon(new ImageIcon("resources/" + f.getIconText() + ".jpg"));
			}
			else
			{
				//Set default values
				temperatureLblList.get(column).setText("/");
				iconLblList.get(column).setIcon(new ImageIcon("resources/NA.jpg"));
			}
		}
		lblLoading.setText("Ready!");
	}

	static class tblCalendarRenderer extends DefaultTableCellRenderer
	{
		public Component getTableCellRendererComponent (JTable table, Object value, boolean selected, boolean focused, int row, int column){
			super.getTableCellRendererComponent(table, value, selected, focused, row, column);
			if (column == 5 || column == 6)
			{ //Colour week-end
				setBackground(new Color(255, 220, 220));
			}
			else
			{ //Colour week
				setBackground(new Color(255, 255, 255));
			}
			if (value != null)
			{
				if (Integer.parseInt(value.toString()) == realDay && currentMonth == realMonth && currentYear == realYear)
				{ //Colour Today
					setBackground(new Color(220, 220, 255));
				}
						
				if(Integer.parseInt(value.toString()) == 99)
				{
					setIcon(icon);
				}
			}
			else
			{
				setIcon(null);
			}
			if(value == null)
			{
				
			}
			setBorder(null);
			setForeground(Color.black);
			
			//clear icons and temperature
			
			
			return this;  
		}
	}
	/** Refreshes the icons to Not Available when updating the weather.
	 * 
	 */
	private static void refreshIcons()
	{
		for(int column = 0;column < 7;column++)
		{
		temperatureLblList.get(column).setText("/");
		iconLblList.get(column).setIcon(new ImageIcon("resources/NA.jpg"));
		}
	}
	
	/**
	 * Action Listener for the previous month button. Adjusts year if going back past January.
	 *
	 */
	static class btnPrevMonth_Action implements ActionListener
	{
		public void actionPerformed (ActionEvent e)
		{
			if (currentMonth == 0)
			{ //Back one year
				currentMonth = 11;
				currentYear -= 1;
			}
			else
			{ //Back one month
				currentMonth -= 1;
			}
			refreshIcons();
			refreshCalendar(currentMonth, currentYear, currentWeek);
		}
		
	}
	/**
	 * Action Listener for the next month button. Adjusts year if going past December.
	 *
	 */
	static class btnNextMonth_Action implements ActionListener
	{
		/* (non-Javadoc)
		 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
		 */
		public void actionPerformed (ActionEvent e)
		{
			if (currentMonth == 11)
			{ //Foward one year
				currentMonth = 0;
				currentYear += 1;
			}
			else
			{ //Foward one month
				currentMonth += 1;
			}
			refreshCalendar(currentMonth, currentYear, currentWeek);
			refreshIcons();
		}
		
	}
	
	/**
	 * Action Listener for the previous week button. Adjusts month and year if necessary if going before the first week.
	 *
	 */
	static class btnPrevWeek_Action implements ActionListener
	{
		public void actionPerformed (ActionEvent e)
		{
			if (currentWeek == 0)
			{
				
				if(currentMonth == 0)
				{ //Back one year
					currentYear--;
					currentMonth = 11;
				}
				else
				{ //Back one month
					currentMonth -= 1;
				}
				//Get now (Number Of Weeks)
				GregorianCalendar cal = new GregorianCalendar(currentYear, currentMonth, 1);
				cal.setMinimalDaysInFirstWeek(1);
				currentWeek = cal.getActualMaximum(GregorianCalendar.WEEK_OF_MONTH)-1; //-1 to match with string[] weeks
			}
			else
			{ //Back one week
				currentWeek -= 1;
			}
			refreshCalendar(currentMonth, currentYear, currentWeek);
			refreshIcons();
		}
		
	}
	
	/**
	 * Action Listener for the next week button. Adjusts month and year if necessary if past the last week of the month.
	 *
	 */
	static class btnNextWeek_Action implements ActionListener
	{
		public void actionPerformed (ActionEvent e)
		{
			//get now (Number Of Weeks)
			GregorianCalendar cal = new GregorianCalendar(currentYear, currentMonth, 1);
			cal.setMinimalDaysInFirstWeek(1);
			int now = cal.getActualMaximum(GregorianCalendar.WEEK_OF_MONTH)-1; //-1 to match with string[] weeks
			if (currentWeek == now)
			{
				if(currentMonth==11)
				{ //Forward one year
					currentYear++;
					currentMonth = 0;
				}
				else
				{ //Foward one month
					currentMonth += 1;
				}
				currentWeek = 0;
			}
			else
			{ //Foward one week
				currentWeek += 1;
			}
			refreshCalendar(currentMonth, currentYear, currentWeek);
			refreshIcons();
		}
	}
	
	static class btnAddUser_Action implements ActionListener
	{
		public void actionPerformed (ActionEvent e)
		{
			String[] properties = new String[1];
			properties[0] = txtEnterNewUsername.getText();
			if(cmbUserSelect.getItemCount() <= 4) //Check if the max amount of users has not been reached already
			{
				DataBaseConnection.insertData(properties,"SunTime_Users");
				System.out.println(properties[0] + " add user to database");
			}
			else
			{
				System.out.println("Maximum amount of users reached (4)");
			}
			
			refreshCalendar(currentMonth, currentYear, currentWeek);
		}
	}
	
	/**
	 * Action Listener for adding an event. Adds the event and location of the event.
	 *
	 */
	static class btnAddEvent_Action implements ActionListener
	{
		public void actionPerformed (ActionEvent e)
		{
			String[] properties = new String[2];
			properties[0] = txtEnterNewEventName.getText();
			properties[1] = txtEnterLocation.getText();
			DataBaseConnection.insertData(properties,"SunTime_Events");
			System.out.println(properties[0] + " add event to database");	
			cmbEventSelect.addItem(txtEnterNewEventName.getText());
			refreshCalendar(currentMonth, currentYear, currentWeek);
		}
	}
	
	/**
	 * Action listener for the forecast button. Performs the forecast and displays it on the icons.
	 *
	 */
	static class btnGetForecast_Action implements ActionListener
	{
		public void actionPerformed (ActionEvent e)
		{
			doForecast();
		}
	}
	/**
	 * Action Listener for the next year button. 
	 *
	 */
	static class cmbYear_Action implements ActionListener
	{
		public void actionPerformed (ActionEvent e)
		{
			if (cmbYear.getSelectedItem() != null)
			{
				String b = cmbYear.getSelectedItem().toString();
				currentYear = Integer.parseInt(b);
				refreshCalendar(currentMonth, currentYear, currentWeek);
			}
			refreshIcons();
		}
	}

	/**
	 * Action Listener for the user select combobox. 
	 *
	 */
	static class cmbUserSelect_Action implements ActionListener
	{
		public void actionPerformed (ActionEvent e)
		{
			if (cmbUserSelect.getSelectedItem() != null)
			{
				selectedUser = cmbUserSelect.getSelectedItem().toString();
				refreshCalendar(currentMonth, currentYear, currentWeek);
			}
		}
	}
	
	/**
	 * Action Listener for the event selection combobox.
	 *
	 */
	static class cmbEventSelect_Action implements ActionListener
	{
		public void actionPerformed (ActionEvent e)
		{
			if (cmbEventSelect.getSelectedItem() != null)
			{
				selectedEvent = cmbEventSelect.getSelectedItem().toString();
				
				try
				{
					CachedRowSet events = DataBaseConnection.getEvents();
					while(events.next())
					{
						if(events.getString(3) == selectedEvent)
						{
							txtEnterLocation.setText(events.getString("Location"));
						}
					}
				}
				catch (SQLException error)
				{
					error.printStackTrace();
				}
				
				refreshCalendar(currentMonth, currentYear, currentWeek);
			}
		}
	}
}